home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 14 / CU Amiga Magazine's Super CD-ROM 14 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-09].iso / CUCD / Programming / XPK / Source / xpkmaster / xpkmaster.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-04-25  |  18.3 KB  |  692 lines

  1. #ifndef XPKMASTER_XPKMASTER_C
  2. #define XPKMASTER_XPKMASTER_C
  3.  
  4. /* Routinesheader
  5.  
  6.     Name:        xpkmaster.c
  7.     Main:        xpkmaster
  8.     Versionstring:    $VER: xpkmaster.c 1.10 (01.04.97)
  9.     Author:        SDI
  10.     Distribution:    PD
  11.     Description:    the main xpk functions
  12.  
  13.  1.0   09.10.96 : first real version
  14.  1.1   27.12.96 : removed 1.3 specific functions
  15.  1.2   10.01.97 : corrected XpkPack's abort
  16.  1.3   11.01.97 : corrected mem bug (reported by Laurent Kempe)
  17.  1.4   30.01.97 : hopefully fixed mem bug finally
  18.  1.5   31.01.97 : bug still occured
  19.  1.6   01.03.97 : added NoPack stuff to XpkWrite and XpkPack
  20.  1.7   24.03.97 : fixed XpkPack
  21.  1.8   25.03.97 : added AutoPasswd
  22.  1.9   28.03.97 : moved autopassword into xpkopen
  23.  1.10  01.04.97 : fixed NoPack error
  24. */
  25.  
  26. #include <pragma/exec_lib.h>
  27. #include <pragma/intuition_lib.h>
  28. #include <pragma/dos_lib.h>
  29. #include <pragma/utility_lib.h>
  30. #include <pragma/xpkmaster_lib.h>
  31. #include <exec/types.h>
  32. #include <exec/memory.h>
  33. #include <exec/tasks.h>
  34. #include <libraries/ppbase.h>
  35. #include <dos/dos.h>
  36. #include "xpkmaster.h"
  37. #include "xpk_strings.h"
  38.  
  39. #ifdef SUPPORT_A4
  40.   LONG XpkOpenA4NAME(struct XpkFib **xfh, struct TagItem *tags, ULONG a4);
  41.   #ifdef __SASC
  42.     #pragma libcall XpkBase XpkOpenA4NAME 036 C9803
  43.   #else
  44.     #pragma amicall(XpkBase,0x36,XpkOpenA4NAME(a0,a1,a4))
  45.   #endif
  46. #else
  47.   #define XpkOpenA4NAME XpkOpen
  48. #endif
  49.  
  50. /**************************************************************************
  51.  *
  52.  *   XpkPack() - pack a file
  53.  *
  54.  */
  55.  
  56. #ifdef __cplusplus
  57.   extern "C"
  58. #endif
  59.  
  60. LONG __asm LIBXpkPack(register __a0 struct TagItem *tags A4PROTO)
  61. {
  62.   struct XpkBuffer *xbuf = 0;
  63.   STRPTR buf;
  64.   LONG totlen, res, chunklen;
  65.  
  66.   if(!FindTagItem(XPK_PackMethod, tags))
  67.     return XPKERR_BADPARAMS;
  68.  
  69.   if((res = XpkOpenA4NAME((struct XpkFib **) &xbuf, tags A4SUPP)))
  70.     return res;
  71.  
  72.   totlen = xbuf->xb_InLen;
  73.  
  74.   CurrentTime(&xbuf->xb_Secs, &xbuf->xb_Mics); /* Start the clock */
  75.  
  76.   xbuf->xb_Prog.xp_Type = XPKPROG_START;
  77.   xbuf->xb_Prog.xp_ULen = totlen;
  78.   if(callprogress(xbuf))
  79.     return XpkClose((struct XpkFib *) xbuf);
  80.  
  81.   while(totlen > 0)
  82.   {
  83.     chunklen = xbuf->xb_Fib.xf_NLen;
  84.  
  85.     if(!(buf = (STRPTR) hookread(xbuf, XIO_READ, NULL, chunklen)))
  86.       break;
  87.  
  88.     if(XpkWrite((struct XpkFib *) xbuf, buf, chunklen))
  89.       break;
  90.  
  91.     totlen -= chunklen;
  92.  
  93.     xbuf->xb_Prog.xp_Type = XPKPROG_MID;    /* Progress report     */
  94.     xbuf->xb_Prog.xp_UCur += chunklen;
  95.     xbuf->xb_Prog.xp_CCur = xbuf->xb_Fib.xf_CCur;
  96.     if(callprogress(xbuf))
  97.       return XpkClose((struct XpkFib *) xbuf);
  98.   }
  99.  
  100.   if(xbuf->xb_Prog.xp_Type)
  101.   {
  102.     xbuf->xb_Prog.xp_Type = XPKPROG_END;
  103.     xbuf->xb_Prog.xp_CCur += xbuf->xb_Headers.h_LocSize;
  104.     xbuf->xb_Prog.xp_Activity = xbuf->xb_Result ?
  105.       strings[TXT_ABORTED] : xbuf->xb_LastMsg;
  106.     callprogress(xbuf);     /* Call the hook one last time */
  107.   }
  108.  
  109.   return XpkClose((struct XpkFib *) xbuf);
  110. }
  111.  
  112. /*********************************************************************
  113.  *
  114.  * XpkUnpack - unpack a file
  115.  *
  116.  */
  117.  
  118. #ifdef __cplusplus
  119.   extern "C"
  120. #endif
  121.  
  122. LONG __asm LIBXpkUnpack(register __a0 struct TagItem *tags A4PROTO)
  123. {
  124.   struct XpkBuffer *xbuf = NULL;
  125.   STRPTR pointer;
  126.   LONG len, res;
  127.  
  128.   if((res = XpkOpenA4NAME((struct XpkFib **) &xbuf, tags A4SUPP)))
  129.     return res;
  130.  
  131.   if(xbuf->xb_Flags & XMF_PACKING)
  132.   {
  133.     xbuf->xb_Result = XPKERR_BADPARAMS;
  134.     goto Abort;
  135.   }
  136.  
  137.   CurrentTime(&xbuf->xb_Secs, &xbuf->xb_Mics); /* Start the clock */
  138.  
  139.   xbuf->xb_Prog.xp_Type = XPKPROG_START;    /* Initialize progress */
  140.   xbuf->xb_Prog.xp_ULen = xbuf->xb_ULen;
  141.   if(callprogress(xbuf))
  142.     goto Abort;
  143.  
  144.   if(!hookwrite(xbuf, XIO_TOTSIZE, NULL, xbuf->xb_Fib.xf_ULen + XPK_MARGIN))
  145.   {
  146. #ifdef DEBUG
  147.     DebugError("XpkUnpack: XIO_TOTSIZE failed");
  148. #endif
  149.     goto Abort;
  150.   }
  151.  
  152.   if(!(pointer = (STRPTR) hookwrite(xbuf, XIO_GETBUF, 0, xbuf->xb_Fib.xf_NLen)))
  153.   {
  154. #ifdef DEBUG
  155.     DebugError("XpkUnpack: XIO_GETBUF failed (a)");
  156. #endif
  157.     goto Abort;
  158.   }
  159.  
  160. #ifdef DEBUG
  161.   if(xbuf->xb_Result)
  162.     DebugError("XpkUnpack: failure before unpackloop");
  163. #endif
  164.  
  165.   while((len = XpkRead((struct XpkFib *) xbuf, pointer, XPKLEN_ONECHUNK)) > 0)
  166.   {
  167.     if(!hookwrite(xbuf, XIO_WRITE, pointer, len))
  168.     {
  169. #ifdef DEBUG
  170.       DebugError("XpkUnpack: XIO_WRITE failed");
  171. #endif
  172.       goto Abort;
  173.     }
  174.  
  175.     xbuf->xb_Prog.xp_Type = XPKPROG_MID;    /* Progress report     */
  176.     xbuf->xb_Prog.xp_CCur = xbuf->xb_Fib.xf_CCur;
  177.     xbuf->xb_Prog.xp_UCur = xbuf->xb_Fib.xf_UCur;
  178.     if(callprogress(xbuf))
  179.       goto Abort;
  180.  
  181.     if(!(pointer = (STRPTR) hookwrite(xbuf, XIO_GETBUF, NULL, xbuf->xb_Fib.xf_NLen)))
  182.     {
  183. #ifdef DEBUG
  184.       DebugError("XpkUnpack: XIO_GETBUF failed (b)");
  185. #endif
  186.       goto Abort;
  187.     }
  188.   }
  189.  
  190.   xbuf->xb_Result = len;
  191. #ifdef DEBUG
  192.   if(xbuf->xb_Result)
  193.     DebugError("XpkUnpack: XpkRead failed with %ld", xbuf->xb_Result);
  194. #endif
  195.  
  196.   if(xbuf->xb_Prog.xp_Type)
  197.   {
  198.     xbuf->xb_Prog.xp_Type = XPKPROG_END;
  199.     xbuf->xb_Prog.xp_Activity = xbuf->xb_Result ? strings[TXT_ABORTED] : xbuf->xb_LastMsg;
  200.     callprogress (xbuf);    /* Call the hook one last time */
  201.   }
  202. Abort:
  203.   return XpkClose((struct XpkFib *) xbuf);
  204. }
  205.  
  206. /*********************************************************************
  207.  *
  208.  * XpkOpen - open a file for packing/unpacking
  209.  *
  210.  */
  211.  
  212. #ifdef __cplusplus
  213.   extern "C"
  214. #endif
  215.  
  216. LONG __asm LIBXpkOpen(register __a0 struct XpkBuffer **xbufp,
  217.     register __a1 struct TagItem *tags A4PROTO)
  218. {
  219. #if defined(DEBUG) && defined(SUPPORT_A4)
  220.   DebugRunTime("XpkOpen: A4 = %ld", a4);
  221. #elif defined(DEBUG)
  222.   DebugRunTime("XpkOpen");
  223. #endif
  224.   return xpkopen(xbufp, tags, 0 A4SUPP);
  225. }
  226.  
  227. /**************************************************************************
  228.  *
  229.  *   XpkExamine() - inspect a compressed file
  230.  *
  231.  */
  232.  
  233. #ifdef __cplusplus
  234.   extern "C"
  235. #endif
  236.  
  237. LONG __asm LIBXpkExamine(register __a0 struct XpkFib *fib,
  238.     register __a1 struct TagItem *tags A4PROTO)
  239. {
  240.   struct XpkBuffer *dummy;
  241.   LONG res;
  242.  
  243. #if defined(DEBUG) && defined(SUPPORT_A4)
  244.   DebugRunTime("XpkExamine: A4 = %ld", a4);
  245. #elif defined(DEBUG)
  246.   DebugRunTime("XpkExamine");
  247. #endif
  248.  
  249.   if((res = xpkopen(&dummy, tags, 1 A4SUPP)))
  250.     return res;
  251.  
  252.   CopyMem(dummy, fib, sizeof(struct XpkFib));
  253.   // copies the entries of XpkFib
  254.   // *fib = dummy->Fib works too, but calls it's own copy-function
  255.  
  256.   return XpkClose((struct XpkFib *) dummy);
  257. }
  258.  
  259. /**************************************************************************
  260.  *
  261.  *   XpkRead() - read one chunk from a compressed file
  262.  *
  263.  */
  264.  
  265. #ifdef __cplusplus
  266.   extern "C"
  267. #endif
  268.  
  269. LONG __asm LIBXpkRead(register __a0 struct XpkBuffer *xbuf,
  270.     register __a1 STRPTR buf, register __d0 ULONG len)
  271. {
  272.   struct XpkSubParams *xpar;
  273.   struct Library *XpkSubBase = xbuf->xb_SubBase;
  274.   XpkChunkHeader *lochdr = &(xbuf->xb_Headers.h_Loc);
  275.   LONG ulen, clen, rclen, lochdrsize = xbuf->xb_Headers.h_LocSize;
  276.   ULONG csum;
  277.   ULONG maxon_bug; // remove later all assigns to this var - only workaround
  278.            // for MaxonC++ bug
  279.  
  280. #ifdef DEBUG
  281.   DebugRunTime("XpkRead");
  282. #endif
  283.  
  284.   if(!xbuf)
  285.     return XPKERR_NOFUNC;
  286.  
  287.   if(xbuf->xb_Flags & XMF_EOF)
  288.     return 0;
  289.  
  290.   switch(xbuf->xb_Format) 
  291.   {
  292.     /*********************** Unpack standard XPK *******************/
  293.   case XPKMODE_UPSTD:
  294.     if(lochdr->xch_Word.xchw_Type == XPKCHUNK_END)
  295.       return 0;
  296.  
  297. // remove (maxon_bug = ..) later, when Maxon removed the bug!
  298.     if((maxon_bug = hchecksum((STRPTR) lochdr, lochdrsize)))
  299.     {
  300. #ifdef DEBUG
  301.       DebugError("XpkRead: hchecksum(,%ld) failed", lochdrsize);
  302. #endif
  303.       return(xbuf->xb_Result = XPKERR_CHECKSUM);
  304.     }
  305.  
  306.     if(xbuf->xb_Headers.h_Glob.xsh_Flags & XPKSTREAMF_LONGHEADERS)
  307.       ulen = lochdr->xch_Long.xchl_ULen, clen = lochdr->xch_Long.xchl_CLen;
  308.     else
  309.       ulen = lochdr->xch_Word.xchw_ULen, clen = lochdr->xch_Word.xchw_CLen;
  310.     rclen = ROUNDLONG(clen);
  311.  
  312.     if(lochdr->xch_Word.xchw_Type == XPKCHUNK_RAW)
  313.     {
  314. // remove later assignment
  315.       if(!(maxon_bug = (ULONG) hookread(xbuf, XIO_READ, buf, rclen + lochdrsize)))
  316.     return xbuf->xb_Result;
  317.  
  318.       if(!(xbuf->xb_Flags & XMF_NOCRC))
  319.     if((csum=cchecksum((ULONG *) buf, rclen >>2)) != lochdr->xch_Word.xchw_CChk)
  320.     {
  321. #ifdef DEBUG
  322.       DebugError("XpkRead: cchecksum(,%ld) = %lx != %lx failed", rclen >> 2, csum, (ULONG) lochdr->xch_Word.xchw_CChk);
  323. #endif
  324.       return (xbuf->xb_Result = XPKERR_CHECKSUM);
  325.         }
  326.  
  327.       CopyMem(buf + rclen, lochdr, lochdrsize);
  328.     }
  329.     else if(lochdr->xch_Word.xchw_Type == XPKCHUNK_PACKED)
  330.     {
  331.       xpar = &xbuf->xb_PackParam;
  332.       if(!(xpar->xsp_InBuf = hookread(xbuf, XIO_READ, NULL, rclen + lochdrsize)))
  333.     return xbuf->xb_Result;
  334.  
  335.       if(!(xbuf->xb_Flags & XMF_NOCRC))
  336.     if((csum=cchecksum((ULONG *)xpar->xsp_InBuf, rclen >> 2)) != lochdr->xch_Word.xchw_CChk)
  337.     {
  338. #ifdef DEBUG
  339.       DebugError("XpkRead: cchecksum(,%ld) = %lx != %lx failed", rclen >>2 , csum, (ULONG) lochdr->xch_Word.xchw_CChk);
  340. #endif
  341.       return (xbuf->xb_Result = XPKERR_CHECKSUM);
  342.         }
  343.       xbuf->xb_Flags |= XMF_INITED;
  344.  
  345.       xpar->xsp_InLen = clen;
  346.       xpar->xsp_OutLen = ulen;
  347.       xpar->xsp_OutBufLen = ulen;
  348.       xpar->xsp_Number = 0;
  349.       xpar->xsp_OutBuf = buf;
  350.       xpar->xsp_Password = xbuf->xb_Password;
  351.       xpar->xsp_LibVersion = xbuf->xb_Headers.h_Glob.xsh_SubVrs;
  352.  
  353.       if((xbuf->xb_Result = XpksUnpackChunk(xpar)))
  354.       {
  355.     return xbuf->xb_Result;
  356.       }
  357.  
  358.       CopyMem((STRPTR) xpar->xsp_InBuf + rclen, lochdr, lochdrsize);
  359.     }
  360.     else
  361.       return (xbuf->xb_Result = XPKERR_CORRUPTPKD);
  362.  
  363.     updatefib(xbuf);
  364.     return ulen;
  365.  
  366.     /********************* Unpack powerpacked file ****************/
  367.   case XPKMODE_UPPP:
  368.     {
  369. #ifdef USE_POWERPACKER
  370.       struct Library *PPBase = xbuf->xb_SubBase;
  371.       STRPTR inbuf, inbufend;
  372.  
  373.       if(!(inbuf = (STRPTR) hookread(xbuf, XIO_READ, NULL, xbuf->xb_InLen - 4)))
  374.         return xbuf->xb_Result;
  375.       inbufend = inbuf + xbuf->xb_InLen - 4;
  376.  
  377.       ppDecrunchBuffer(inbufend, buf, (ULONG *) inbuf, DECR_NONE);
  378.  
  379.       xbuf->xb_Fib.xf_CCur = xbuf->xb_InLen;
  380.       xbuf->xb_Fib.xf_UCur = xbuf->xb_Fib.xf_ULen;
  381.       xbuf->xb_Fib.xf_NLen = 0;
  382.       xbuf->xb_Flags |= XMF_EOF;
  383.  
  384.       return (LONG) xbuf->xb_ULen;
  385. #else
  386.       return (xbuf->xb_Result = XPKERR_NOFUNC);
  387. #endif /* USE_POWERPACKER */
  388.     }
  389.  
  390.     /********************* Unpack unpacked file *******************/
  391.   case XPKMODE_UPUP:
  392.     {
  393.       ULONG len = xbuf->xb_Fib.xf_ULen - xbuf->xb_Fib.xf_CCur;
  394.  
  395.       if(len > CHUNKSIZE)
  396.         len = CHUNKSIZE;
  397.       else
  398.         xbuf->xb_Flags |= XMF_EOF;
  399.  
  400. // maxon_bug later should be removed
  401.       if(!(maxon_bug = (ULONG)hookread(xbuf, XIO_READ, buf, len)))
  402.         return xbuf->xb_Result;
  403.  
  404.       xbuf->xb_Fib.xf_CCur += len;
  405.       xbuf->xb_Fib.xf_UCur += len;
  406.       xbuf->xb_Fib.xf_NLen = Min(xbuf->xb_InLen - xbuf->xb_Fib.xf_UCur, CHUNKSIZE) + XPK_MARGIN;
  407.  
  408.       return (LONG) len;
  409.     }
  410.   }
  411.  
  412.   return xbuf->xb_Result;
  413. }
  414.  
  415. /**************************************************************************
  416.  *
  417.  *   XpkWrite() - write a chunk to a compressed file
  418.  *
  419.  */
  420.  
  421. #ifdef __cplusplus
  422.   extern "C"
  423. #endif
  424.  
  425. LONG __asm LIBXpkWrite(register __a0 struct XpkBuffer *xbuf,
  426.     register __a1 STRPTR buf, register __d0 ULONG ulen)
  427. {
  428.   struct Library *XpkSubBase = xbuf->xb_SubBase;
  429.   struct XpkSubParams *xpar;
  430.   struct Headers *head = &xbuf->xb_Headers;
  431.   LONG clen, rclen, outbuflen;
  432.   UWORD end[2] = {0,0}; /* last ULONG of buffer, when not longword bounded */
  433.   UBYTE type;
  434.   STRPTR outbuf;
  435.   ULONG maxon_bug; //remove later after correction of bug
  436.  
  437.   if(!xbuf->xb_FirstChunk)
  438.     xbuf->xb_FirstChunk = ulen;
  439.   if(ulen > xbuf->xb_FirstChunk)
  440.     return (xbuf->xb_Result = XPKERR_BADPARAMS);
  441.  
  442.   if(xbuf->xb_Flags & XMF_NOPACK) // no packing
  443.   {
  444.     hookwrite(xbuf, XIO_WRITE, buf, ulen);
  445.     xbuf->xb_Fib.xf_UCur += ulen;
  446.     xbuf->xb_Fib.xf_CCur += ulen;
  447.     xbuf->xb_Fib.xf_NLen = Min(xbuf->xb_InLen - xbuf->xb_Fib.xf_UCur,
  448.       (LONG) xbuf->xb_ChunkSize);
  449.     return xbuf->xb_Result;
  450.   }
  451.  
  452.   /******************* Write the GlobHdr ********************/
  453.   if(!(xbuf->xb_Flags & XMF_GLOBHDR))
  454.   {
  455.     if(!xbuf->xb_Password)
  456.       CopyMem(buf, head->h_Glob.xsh_Initial, Min(16, ulen));
  457.     xbuf->xb_Flags |= XMF_GLOBHDR;
  458. // maxon_bug later should be removed
  459.     if(!(maxon_bug = (ULONG) hookwrite(xbuf, XIO_WRITE, &head->h_Glob,
  460.     sizeof(struct XpkStreamHeader))))
  461.       return xbuf->xb_Result;
  462.     xbuf->xb_Fib.xf_CCur += sizeof(struct XpkStreamHeader);
  463.   }
  464.  
  465.   /******************* Allocate the buffer *****************/
  466.   outbuflen = ROUNDLONG(ulen + (ulen>>5) + head->h_LocSize) + XPK_MARGIN;
  467.   if(!(outbuf = (STRPTR) hookwrite(xbuf, XIO_GETBUF, NULL, outbuflen)))
  468.     return xbuf->xb_Result;
  469.  
  470.   outbuf += head->h_LocSize;
  471.   /* compress to behind local header. This is needed by mem-out hook! */
  472.  
  473.   if(ulen < xbuf->xb_MinChunk)
  474.     goto copychunk;
  475.  
  476.   /******************* Pack the chunk **********************/
  477.   xpar = &xbuf->xb_PackParam;
  478.   xpar->xsp_InBuf = buf;
  479.   xpar->xsp_InLen = ulen;
  480.   xpar->xsp_OutBuf = outbuf;
  481.   xpar->xsp_OutBufLen = outbuflen - head->h_LocSize;
  482.   xpar->xsp_Number += 1;
  483.   xpar->xsp_Mode = xbuf->xb_PackingMode;
  484.   xpar->xsp_Password = xbuf->xb_Password;
  485.   xpar->xsp_LibVersion = xbuf->xb_SubInfo->xi_LibVersion;
  486.  
  487.   xbuf->xb_Result = XpksPackChunk(xpar);
  488.   xbuf->xb_Flags |= XMF_INITED;
  489.  
  490.   type = XPKCHUNK_PACKED;
  491.   clen = xpar->xsp_OutLen;
  492.  
  493.   if(xbuf->xb_Result == XPKERR_EXPANSION)
  494.   {
  495.     xbuf->xb_Result = 0;
  496. copychunk:
  497.     type = XPKCHUNK_RAW;
  498.     clen = ulen;
  499.     outbuf = buf;
  500.   }
  501.  
  502.   if(xbuf->xb_Result)
  503.     return xbuf->xb_Result;
  504.  
  505.   /******************* Write the chunk **********************/
  506.   head->h_Loc.xch_Word.xchw_Type = type;
  507.   if(head->h_Glob.xsh_Flags & XPKSTREAMF_LONGHEADERS)
  508.   {
  509.     head->h_Loc.xch_Long.xchl_ULen = ulen;
  510.     head->h_Loc.xch_Long.xchl_CLen = clen;
  511.   }
  512.   else
  513.   {
  514.     head->h_Loc.xch_Word.xchw_ULen = (WORD) ulen;
  515.     head->h_Loc.xch_Word.xchw_CLen = (WORD) clen;
  516.   }
  517.  
  518.   if((rclen = clen&3))
  519.   {
  520.     clen -= rclen;
  521.     CopyMem(outbuf+clen, &end, rclen); /* copy the remaining bytes (max 3) */
  522.   }
  523.  
  524.   head->h_Loc.xch_Word.xchw_CChk = cchecksum((ULONG *) outbuf, clen >> 2)
  525.     ^ end[0] ^ end[1];
  526.   /* add the rest bytes to the checksum */
  527.   
  528.   head->h_Loc.xch_Word.xchw_HChk = 0;
  529.   head->h_Loc.xch_Word.xchw_HChk = hchecksum((STRPTR) &head->h_Loc, head->h_LocSize);
  530.  
  531. // maxon_bug later should be removed
  532.   if(!(maxon_bug = (ULONG) hookwrite(xbuf, XIO_WRITE, &head->h_Loc, head->h_LocSize)))
  533.     return xbuf->xb_Result;
  534.  
  535. // remove
  536.   if(!(maxon_bug = (ULONG) hookwrite(xbuf, XIO_WRITE, outbuf, clen)))
  537.     return xbuf->xb_Result;
  538.  
  539.   if(rclen)
  540.   {
  541. // remove maxon_bug
  542.     if(!(maxon_bug = (ULONG) hookwrite(xbuf, XIO_WRITE, &end, 4)))
  543.       return xbuf->xb_Result;
  544.     clen += 4;
  545.   }
  546.  
  547.   head->h_Glob.xsh_ULen += ulen;
  548.   
  549.   xbuf->xb_Fib.xf_UCur += ulen;
  550.   xbuf->xb_Fib.xf_CCur += head->h_LocSize + clen;
  551.   xbuf->xb_Fib.xf_NLen = Min(max(xbuf->xb_InLen, head->h_Glob.xsh_ULen) -
  552.     xbuf->xb_Fib.xf_UCur, (LONG) xbuf->xb_ChunkSize);
  553.  
  554.   return xbuf->xb_Result;
  555. }
  556.  
  557. /**************************************************************************
  558.  *
  559.  *   XpkSeek() - move around on a compressed file
  560.  *
  561.  */
  562.  
  563. #ifdef __cplusplus
  564.   extern "C"
  565. #endif
  566.  
  567. LONG __asm LIBXpkSeek(register __a0 struct XpkBuffer *xbuf,
  568.     register __d0 LONG dist, register __d1 LONG mode)
  569. {
  570.   xbuf->xb_Result = XPKERR_NOFUNC;
  571.   parsegettags(xbuf);
  572.  
  573.   return xbuf->xb_Result;
  574. }
  575.  
  576. /**************************************************************************
  577.  *
  578.  *   XpkClose() - finish (de)compressing an XPK file
  579.  *
  580.  */
  581.  
  582. #ifdef __cplusplus
  583.   extern "C"
  584. #endif
  585.  
  586. LONG __asm LIBXpkClose(register __a0 struct XpkBuffer *xbuf)
  587. {
  588.   struct Library *XpkSubBase = xbuf->xb_SubBase;
  589.   struct Headers *head = &xbuf->xb_Headers;
  590.   LONG outlen;
  591.  
  592.   if(!xbuf)
  593.     return 0;
  594.  
  595. #ifdef DEBUG
  596.   if(xbuf->xb_Result)
  597.     DebugError("XpkClose: failed (%ld) before XpkClose", xbuf->xb_Result);
  598. #endif
  599.  
  600.   switch(xbuf->xb_Format)
  601.   {
  602. //  case XPKMODE_UPPP:
  603. //    break;
  604.   case XPKMODE_PKSTD:
  605.     {
  606.       if(!xbuf->xb_Result && !(xbuf->xb_Flags & XMF_GLOBHDR|XMF_NOPACK))
  607.       {
  608.  
  609.         hookwrite(xbuf, XIO_WRITE, &head->h_Glob, sizeof(struct XpkStreamHeader));
  610. #ifdef DEBUG
  611.         if(xbuf->xb_Result) DebugError("XpkClose: failed to write globhdr");
  612. #endif
  613.         xbuf->xb_Fib.xf_CCur += sizeof(struct XpkStreamHeader);
  614.       }
  615.       if(!xbuf->xb_Result && !(xbuf->xb_Flags & XMF_NOPACK))
  616.       {
  617.         /******************* Write final chunk header *****************/
  618.         memset(&head->h_Loc, 0, head->h_LocSize);
  619.         head->h_Loc.xch_Word.xchw_Type = XPKCHUNK_END;
  620.         head->h_Loc.xch_Word.xchw_HChk = 0;
  621.         head->h_Loc.xch_Word.xchw_HChk =
  622.           hchecksum((STRPTR) &head->h_Loc, head->h_LocSize);
  623.  
  624.         hookwrite(xbuf, XIO_WRITE, &head->h_Loc, head->h_LocSize);
  625. #ifdef DEBUG
  626.         if(xbuf->xb_Result) DebugError("XpkClose: failed to write lochdr");
  627. #endif
  628.         xbuf->xb_Fib.xf_CCur += head->h_LocSize;
  629.         outlen = xbuf->xb_Fib.xf_CCur;
  630.  
  631.         /********************** Write global header *******************/
  632.         hookwrite(xbuf, XIO_SEEK, NULL, -outlen);
  633. #ifdef DEBUG
  634.         if(xbuf->xb_Result) DebugError("XpkClose: failed to reset output");
  635. #endif
  636.  
  637.         head->h_Glob.xsh_Pack = XPK_COOKIE;
  638.         head->h_Glob.xsh_CLen = outlen - 8;
  639.         head->h_Glob.xsh_HChk = 0;
  640.         head->h_Glob.xsh_HChk =
  641.           hchecksum((STRPTR) &head->h_Glob, sizeof(struct XpkStreamHeader));
  642.  
  643.         hookwrite(xbuf, XIO_WRITE, &head->h_Glob, sizeof(struct XpkStreamHeader));
  644. #ifdef DEBUG
  645.         if(xbuf->xb_Result) DebugError("XpkClose: failed updating globalhdr");
  646. #endif
  647.  
  648.         hookwrite(xbuf, XIO_SEEK, 0, outlen - sizeof(struct XpkStreamHeader));
  649. #ifdef DEBUG
  650.         if(xbuf->xb_Result) DebugError("XpkClose: failed to SEEK to end of output");
  651. #endif
  652.       }
  653.       xbuf->xb_Fib.xf_CLen = xbuf->xb_Fib.xf_CCur;
  654.       xbuf->xb_Fib.xf_ULen = xbuf->xb_Fib.xf_UCur;
  655.  
  656.       /*************************** Shut down *************************/
  657.       if(xbuf->xb_Flags & XMF_INITED)
  658.         XpksPackFree(&xbuf->xb_PackParam);
  659.     }
  660.     break;
  661.   case XPKMODE_UPSTD:
  662.     if(xbuf->xb_Flags & XMF_INITED)
  663.       XpksUnpackFree(&xbuf->xb_PackParam);
  664.     break;
  665.   }
  666.  
  667.   hookread(xbuf, xbuf->xb_Result ? XIO_ABORT : XIO_FREE, NULL, 0);
  668. #ifdef DEBUG
  669.   if(xbuf->xb_Result) DebugError("XpkClose: failed read ABORT/FREE");
  670. #endif
  671.  
  672.   hookwrite(xbuf, xbuf->xb_Result ? XIO_ABORT : XIO_FREE, NULL, 0);
  673. #ifdef DEBUG
  674.   if(xbuf->xb_Result) DebugError("XpkClose: failed write ABORT/FREE");
  675. #endif
  676.  
  677.   if(xbuf->xb_Result && xbuf->xb_Result != XPKERR_CHECKSUM && xbuf->xb_OutName)
  678.     DeleteFile(xbuf->xb_OutName);
  679.  
  680.   parsegettags(xbuf);        /* Send information to the user */
  681.  
  682. #ifdef DEBUG
  683.     DebugRunTime("XpkClose: InLen %ld, CLen %ld, ULen %ld, ID %.4s", xbuf->xb_InLen,
  684.     xbuf->xb_Fib.xf_CLen, xbuf->xb_Fib.xf_ULen, &xbuf->xb_SubID);
  685. #endif
  686.  
  687.   return freebufs(xbuf);
  688. }
  689.  
  690. #endif /* XPKMASTER_XPKMASTER_C */
  691.  
  692.